package org.itboys.seller.service;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.itboys.oss.OssService;
import org.itboys.seller.constant.CaliforniaSiteConstant;
import org.itboys.seller.dto.InfoMatchBO;
import org.itboys.seller.entity.ParamSetDB;
import org.itboys.seller.mapper.InfoPublishMapper;
import org.itboys.seller.mapper.MatchInfoMapper;
import org.itboys.seller.meta.InfoPublish;
import org.itboys.seller.meta.InfoPublishExample;
import org.itboys.seller.meta.MatchInfo;
import org.itboys.seller.meta.MatchInfoExample;
import org.itboys.seller.utils.MatchingUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author hzliangchong1@corp.netease.com
 *         Date 2016/10/26.
 */
@Service
public class MatchInfoService {

    private static final Logger logger = LoggerFactory.getLogger(MatchInfoService.class);

    @Resource
    private InfoPublishMapper infoPublishMapper;
    @Resource
    private MatchInfoMapper matchInfoMapper;
    @Resource(name = "ossService")
    private OssService productOssService;
    @Resource
    private ParamSetService paramSetService;
    @Resource
    private WalletService walletService;
    @Resource
    private MatchInfoDao matchInfoDao;

    @Transactional
    public void addRecord(List<Integer> findIndexList, List<InfoPublish> helpList,
                          int helpType, InfoPublish help) {
        long now = System.currentTimeMillis();
        for (int i = 0; i < findIndexList.size(); i++) {
            MatchInfo info = new MatchInfo();
            InfoPublish  publish = helpList.get(findIndexList.get(i));
            if (helpType == CaliforniaSiteConstant.HelpType.ACCEPT) {
                info.setAcceptId(help.getId());
                info.setProviderId(publish.getId());
                info.setProviderAcc(publish.getAccountId());
                info.setAcceptAcc(help.getAccountId());
            } else {
                info.setProviderId(help.getId());
                info.setAcceptId(publish.getId());
                info.setAcceptAcc(publish.getAccountId());
                info.setProviderAcc(help.getAccountId());
            }
            info.setAmount(publish.getAmount());
            info.setCreateTime(now);
            info.setUpdateTime(now);
            info.setFreezeDays(0);
            info.setProfit(0);
            info.setGetState(CaliforniaSiteConstant.GetState.NO_GET);
            info.setState(CaliforniaSiteConstant.InfoState.MATCHED);
            matchInfoMapper.insert(info);
            InfoPublish originPublish;
            if (helpType == CaliforniaSiteConstant.HelpType.PROVIDER) {
                originPublish = infoPublishMapper.selectByPrimaryKey(info.getAcceptId());
            } else {
                originPublish = infoPublishMapper.selectByPrimaryKey(info.getProviderId());
            }
            originPublish.setState(CaliforniaSiteConstant.InfoState.MATCHED);
            originPublish.setUpdateTime(info.getCreateTime());
            infoPublishMapper.updateByPrimaryKeySelective(originPublish);
            logger.info("match success! provider {}, accepter {}, amount {}", info.getProviderId(),
                    info.getAcceptId(), info.getAmount());
        }
        if (CollectionUtils.isNotEmpty(findIndexList)) {
            InfoPublish publish = infoPublishMapper.selectByPrimaryKey(help.getId());
            publish.setState(CaliforniaSiteConstant.InfoState.MATCHED);
            publish.setUpdateTime(now);
            infoPublishMapper.updateByPrimaryKeySelective(publish);
        }
    }

    public List<MatchInfo> getMatchList(int helpType, long id) {
        MatchInfoExample example = new MatchInfoExample();
        if (helpType == CaliforniaSiteConstant.HelpType.PROVIDER) {
            example.createCriteria().andProviderIdEqualTo(id);
        } else {
            example.createCriteria().andAcceptIdEqualTo(id);
        }
        example.setOrderByClause("create_time desc");
        return matchInfoMapper.selectByExample(example);
    }

    public MatchInfo getById(long id) {
        return matchInfoMapper.selectByPrimaryKey(id);
    }

    public List<MatchInfo> queryInfo(String accountId, int offset, int limit) {
        MatchInfoExample example = new MatchInfoExample();
        MatchInfoExample.Criteria criteria1 = example.createCriteria();
        criteria1.andProviderAccEqualTo(accountId);

        MatchInfoExample.Criteria criteria2 = example.createCriteria();
        criteria2.andAcceptAccEqualTo(accountId);

        example.setLimitStart(offset);
        example.setLimitEnd(limit);
        example.setOrderByClause("update_time");
        return matchInfoMapper.selectByExample(example);
    }

    public void playMoneyConfrim(long id, MultipartFile img) {
        if(img != null && !img.isEmpty()){
            String tempFile = null;
            try {
                tempFile = productOssService.upload(img.getInputStream(), CaliforniaSiteConstant.ImgPath.OSS_PATH);
            } catch (IOException e) {
                logger.error("publish id {} upload file error!", id);
                return;
            }
            MatchInfo publish = matchInfoMapper.selectByPrimaryKey(id);
            publish.setCert(CaliforniaSiteConstant.OSS_URL_PREFIX + CaliforniaSiteConstant.ImgPath.OSS_PATH + "/" + tempFile);
            publish.setState(CaliforniaSiteConstant.InfoState.WAIT_CONFIRM);
            publish.setUpdateTime(System.currentTimeMillis());
            matchInfoMapper.updateByPrimaryKeySelective(publish);
        }
    }

    public void leaveMsg(long id, String msg) {
        if (StringUtils.isBlank(msg)) {
            return;
        }
        MatchInfo publish = matchInfoMapper.selectByPrimaryKey(id);
        publish.setMsg(msg);
        matchInfoMapper.updateByPrimaryKeySelective(publish);
    }

    public void calProfit() {
        MatchInfoExample example = new MatchInfoExample();
        long time = System.currentTimeMillis();
        example.createCriteria().andStateEqualTo(CaliforniaSiteConstant.InfoState.CONFIRM)
            .andGetStateEqualTo(CaliforniaSiteConstant.GetState.NO_GET);
        List<MatchInfo> infoList = matchInfoMapper.selectByExample(example);
        logger.info("query can cal profit records waste {}", System.currentTimeMillis() - time);
        ParamSetDB paramSetDB = paramSetService.getParamSet();
        int profit;
        for (MatchInfo info : infoList) {
            profit = new BigDecimal(info.getAmount())
                    .multiply(new BigDecimal(paramSetDB.getProfit()).divide(new BigDecimal(100), BigDecimal.ROUND_FLOOR))
                    .intValue();
            info.setProfit(info.getProfit() + profit);
            info.setFreezeDays(info.getFreezeDays() + 1);
            if (info.getFreezeDays() < paramSetDB.getMinFreezeDays()) {
                info.setFreezeState(CaliforniaSiteConstant.FreezeState.FREEZE);
            } else {
                info.setFreezeState(CaliforniaSiteConstant.FreezeState.UN_FREEZE);
            }
            boolean freeze = false;
            if (info.getFreezeDays() >= paramSetDB.getMaxLeaveDays()) {
                //TODO 放入本息钱包，此条记录变为已提取，同时冻结此人
                info.setGetState(CaliforniaSiteConstant.GetState.GOT);
                freeze = true;
            }
            matchInfoDao.updateMatchInfo(info, freeze);
            //TODO 将收益记入DB中
            logger.info("account {} get profit {}, total profit {}", info.getProviderAcc(), profit, info.getProfit());
        }
    }
}
